package stack;

/**
 * @program: algorithm
 * @description: 下压堆栈(链表实现)先进先出
 * @author: Yan.Zhang
 * @create: 2020-04-23 09:24
 **/
public class Stack<Item>  {

    /**
     * 第一个节点
     */
    private Node first;

    /**
     * 堆栈大小
     */
    private int size;

    /**
     * 堆栈内部节点类
     */
    private class Node{

        /**
         * 泛型数据
         */
        Item item;
        /**
         * 下一个节点
         */
        Node next;
    }

    /**
     * 判断空，也可以使用size == 0
     * @return
     */
    public boolean isEmpty(){
        return first == null ;
    }

    /**
     * 获取大小
     * @return
     */
    public int size(){
        return size;
    }

    /**
     * 添加元素
     * @param item
     */
    public void push (Item item){
        //将第一个节点赋值给变量oldFirst（有货要进来。我把我的货复制一份给你，还有我的位置。）
        Node oldFirst = first;
        //初始化第一个节点（我把我的货扔掉，我现在手里空空，我要拿新货了）
        first = new Node();
        //将传入的参数赋值给第一个节点（我获取到货了）
        first.item = item;
        //第一个节点指向oldFirst（我现在站在你后面了）
        first.next = oldFirst;
        //节点数量加1
        size++;
    }

    /**
     * 移除元素
     * @return
     */
    public Item pop (){
        //拿到第一个节点的数组
        Item item = first.item;
        //将第一个节点的下一个节点赋值给第一个节点（借用push方法的oldFirst，现在oldFirst就是first了）
        first = first.next;
        //节点数量减1
        size--;
        //返回移除的元素数据
        return item;
    }



    public static void main(String[] args){
        Stack<String> stack = new Stack<>();
        stack.push("a");
        stack.push("b");
        stack.push("c");
        System.out.println(stack.size());
        System.out.println(stack.pop());
        System.out.println(stack.size());
    }
}